package com.zrj.auth.config;

import cn.hutool.core.util.StrUtil;
import com.zrj.auth.constant.SecurityConstants;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.ReactiveAuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import reactor.core.publisher.Mono;

import java.net.URI;

/**
 * 自定义鉴权管理器
 * @author zhaorujie
 * @version 1.0
 * @date 2022/3/23 13:13
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class ResourceServerManager implements ReactiveAuthorizationManager<AuthorizationContext> {

    public final StringRedisTemplate redisTemplate;

    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> authentication, AuthorizationContext authorizationContext) {
        ServerHttpRequest request = authorizationContext.getExchange().getRequest();
        //预检请求放行
        if (request.getMethod() == HttpMethod.OPTIONS) {
            return Mono.just(new AuthorizationDecision(true));
        }
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        String methodValue = request.getMethodValue();
        String path = request.getURI().getPath();
        String restfulPath = methodValue + ":" + path;

        //如果token是以"bearer "为前缀的，则说明有效，即已通过认证
        String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_KEY);
        if (StrUtil.isNotEmpty(token) && StrUtil.startWithIgnoreCase(token, SecurityConstants.JWT_PREFIX)) {
            return Mono.just(new AuthorizationDecision(true));
        } else {
            return Mono.just(new AuthorizationDecision(false));
        }

    }
}
